import os
import subprocess
import json

from test import output_path


class Inline_seq():
    def __init__(self,input_path,compile_path,func_name):
        self.input_path=input_path
        file_name = os.path.splitext(os.path.basename(compile_path))[0]
        output_path = os.path.join(os.path.dirname(compile_path), f'{file_name}.txt')
        os.system(f'objdump -d -l "{compile_path}" > "{output_path}"')
        self.assmebly_path= output_path
        self.func_name=func_name+'('
    def find_func(self):
        with open(self.input_path, 'r') as file:
            lines = file.readlines()
            group=None
            results=[]
            for i,line in enumerate(lines,start=1):
                if line.startswith('{'):
            # 保存前一个元素和 '{' 到一个新的分组
                    group = [i-1,lines[i - 2], '{']
                elif line.startswith('}'):
            # 添加 '}' 并将当前分组保存到结果
                    group.append('}')
                    results.append(group)
                    group = None  # 重置分组
                elif group is not None:
            # 如果在 '{' 和 '}' 之间，将元素添加到当前分组
                    group.append(line)
        return results

    def find_inlinefunc(self):
        inline_infors=[]
        for func in self.find_func():
            memmove_index = 0
            one_inline_infor=[]
            for index, element in enumerate(func):
                if self.func_name in str(element) and 'main' not in str(element):
                    memmove_index = index + func[0]
                    called_func=element



                    call_func=func[1]
                    one_inline_infor.append({'call_func':call_func,
                            'memmove_index':memmove_index-1,
                            'called_func':called_func.strip()})

            if one_inline_infor:
                inline_infors.append(one_inline_infor)
        return inline_infors

    def find_inst(self):
        with open(self.assmebly_path, 'r') as file:
            lines = file.readlines()
            all_info=[]
            for item in self.find_inlinefunc():
                for func in item:
                    found = False
                    start_recording = False
                    recorded_lines = []
                    for i, line in enumerate(lines):
                # 如果找到 call_func 行
                        if found:
                            break
                        if line.strip() == func['call_func'].split(' ')[-1].strip()+':':
                    # 从该行之后继续查找 memmove_index
                            for j in range(i + 1, len(lines)):
                                index_line = lines[j]
                        # 如果找到 memmove_index，则从下一行开始记录
                                a=index_line.split(':')[-1].strip()
                                b=str(func['memmove_index'])
                                if a == b:
                                    start_recording = True
                                    continue

                        # 判断是否开始记录符合条件的行
                                if start_recording:
                                    if not lines[j].startswith(" "):  # 如果没有空格开头，则停止记录
                                        start_recording = False
                                        found = True
                                        break
                                    recorded_lines.append(lines[j].strip().replace('\t', ''))
                            func['recorded_lines'] = recorded_lines
            # 将更新后的 item 添加到 all_info 中
                            all_info.append(func)
        with open(f"{func_name}.json", "w") as f:
            json.dump(all_info, f, indent=4)
        return all_info
if __name__ == '__main__':
    input_path='/home/wang/CFG/build3/CWE121_Stack_Based_Buffer_Overflow__CWE193_char_alloca_cpy_01.c' #源文件
    compile_path='/home/wang/CFG/build3/MyExecutabledynamic'  #EFL文件
    func_name='ALLOCA'
    instance=Inline_seq(input_path,compile_path,func_name)
    print(instance.find_inlinefunc())
    instance.find_inst()


